# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
from selenium.webdriver.common.action_chains import ActionChains
import unittest
import random
import time
from cookies import lasthopes, randomword, saved_big_pdata, saved_small_pdata
import re
import string
import sys
from selenium.webdriver.common.keys import Keys
from PIL import Image
from os import remove, listdir, sep
from os.path import basename, isfile
import tempfile
from warnings import warn
from baseclass import BaseClass

class BaseCart(BaseClass):
    def get_cat(self, category=''):
        #Get random category
        cat = random.choice([a for a in WebDriverWait(self.driver, timeout=5).until(lambda dr: dr\
                                        .find_elements_by_css_selector("a.b-header-nav-anchor"))
                                        if category in a.get_attribute("textContent")])
        res = cat.get_attribute("href")
        cat.click()
        WebDriverWait(self.driver, timeout=10).until(lambda dr: \
                            dr.find_element_by_css_selector("div._b-product"))
        return res

    def go_cart(self):
        self.get_url("/showparam/magaz-cart.html")

    def cart_price_ontop(self):
        #Get count items in cart
        ActionChains(self.driver).move_to_element(WebDriverWait(self.driver, timeout=4)\
                    .until(lambda dr: dr.find_element_by_css_selector("p.b-header-top-cart-total"))).perform()
        ctext = ''
        try:
            ctext = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                                       .find_element_by_css_selector("p.b-header-top-cart-total")).text
            return int(re.sub('\D', '', ctext))
        except:
            print 'Can\'t get price from '+ctext
            return 0

    def clear_cart(self):
        if self.cart_items_ontop()==0:
            print "Cart already empty"
            return
        warn("Cart have items")
        self.go_cart()
        #Clear and check
        count_bfr = self.cart_items_ontop()
        mass_ops = WebDriverWait(self.driver, timeout=10).until(lambda dr: [a for a in
                                        dr.find_elements_by_css_selector("span.g-pseudo-h") if\
                                                       a.get_attribute("textContent")==u'Массовые операции'])[0]
        mass_ops.click()
        mass_clear = WebDriverWait(self.driver, timeout=10).until(lambda dr: [a for a in
                                        dr.find_elements_by_css_selector("span.g-pseudo-h") if\
                                                       a.get_attribute("textContent")==u'Очистить корзину'])[0]
        mass_clear.click()
        ##Check for count decreased
        WebDriverWait(self.driver, timeout=10).until(lambda dr: self.cart_items_ontop()==0)

    def get_item(self):
        #Get random item
        itm = random.choice([a for a in WebDriverWait(self.driver, timeout=10)\
                           .until(lambda dr: dr.find_elements_by_css_selector("a._b-product-image"))\
                             if a.is_displayed()])
        res = itm.get_attribute("href")
        itm.click()
        return res
   
    def current_price(self):
        try:
            pricestr = WebDriverWait(self.driver, timeout=5).until(lambda dr: dr\
                        .find_element_by_css_selector("p.b-goods-price-current"))
            return int(re.sub('\D', '', pricestr.text))
        except:
            print "Can't get price from item page"
            return 0

    def buy_item(self):
        #Buy button on item page
        try: buy = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                          .find_element_by_css_selector("span.b-goods-price-btn.b-goods-price-btn_blue.js-btn-buy"))
        except: return False
        res = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                          .find_element_by_css_selector("p.b-goods-price-current")).text
        count_bfr = self.cart_items_ontop()
        buy.click()
        #Check for count increased
        WebDriverWait(self.driver, timeout=30).until(lambda dr: self.cart_items_ontop()>count_bfr)
        return res
    def price_in_order(self):
        new_pricestr = WebDriverWait(self.driver, timeout=10)\
                           .until(lambda dr: dr.find_element_by_css_selector("b.js-total-value")).text
        return int(re.sub('\D', '', new_pricestr))
    def cart_items_ontop(self):
        ctext = ''
        try:
            #Get count items in cart
            ActionChains(self.driver).move_to_element(WebDriverWait(self.driver, timeout=5)\
                        .until(lambda dr: dr.find_element_by_css_selector("p.b-header-top-cart-total"))).perform()
            ctext = WebDriverWait(self.driver, timeout=5).until(lambda dr: \
                     dr.find_element_by_css_selector("p.b-header-top-cart-title")).text
            return int(re.sub('\D', '', ctext))
        except:
            print 'Can\'t get count from '+ctext
            return 0

    def perform_order(self):
        #Continue to buy
        buy_cont = WebDriverWait(self.driver, timeout=10)\
                               .until(lambda dr: dr.find_element_by_name("buy_from_cart"))
        assert u'Оформить заказ' in buy_cont.get_attribute("value")
        buy_cont.click()
        #Detect if offer page shows
        return WebDriverWait(self.driver, timeout=10)\
                    .until(lambda dr: dr.find_element_by_css_selector("div.b-order-block"))
    
    def change_city(self, city = ''):
        if self.isauth:
            return self.driver.find_element_by_css_selector\
                   ("span.b-header-top-region.js-top-region").text
        #Change location
        curr_loc_lnk = self.driver.find_element_by_css_selector("div.b-order-block.mod_delivery")\
                             .find_element_by_css_selector("span.g-pseudo-h")
        curr_loc_lnk.click()
        ##Location search tooltip
        new_loc_frm = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                                                .find_element_by_css_selector("form.b-form.mod_location-search"))
        newcit = WebDriverWait(new_loc_frm, timeout=10).until(lambda dr: dr\
                                                .find_element_by_css_selector("span.g-pseudo-h"))
        newcit_name = city or newcit.text
        loc_srch = new_loc_frm.find_element_by_name("location-search")
        loc_srch.send_keys(newcit_name)
        self.shot_an_element(new_loc_frm, "location_tooltip")
        loc_srch.send_keys(Keys.ENTER)
        ##Wait for city suggestion and click.
        try:
            loc_srch.click()
            WebDriverWait(self.driver, timeout=5).until(lambda dr: dr\
                                              .find_element_by_css_selector("div.b-suggestion-item")).click()
        except:
            warn("city suggestion wasn't appeared")
        ##Wait fow new city applies
        WebDriverWait(self.driver, timeout=10).until(lambda dr: \
                            newcit_name in dr.find_element_by_css_selector("div.b-order-block.mod_delivery")\
                             .find_element_by_css_selector("span.g-pseudo-h").text)
        time.sleep(3) #Wait until city really fucking changed on server
        return newcit_name

    def get_delivery(self, preferred = ''):
        #Select devivery
        del_blk = self.driver.find_element_by_css_selector("div.b-order-block.mod_delivery")
        self.shot_an_element(del_blk, "delivery_block")
        ActionChains(self.driver).move_to_element(del_blk).perform()
        rbs_all = del_blk.find_elements_by_css_selector("div.b-order-options-card.toolbar_on")
        rbs_bad = del_blk.find_elements_by_css_selector("div.b-order-options-card.toolbar_on.state_disabled")
        rbs_delivers = [a.find_element_by_css_selector("span.g-pseudo-h.g-link") for a in rbs_all \
                        if preferred in a.text and not a in rbs_bad]
        rbs_deliver = random.choice(rbs_delivers)
        rbs_deliver.click()
        return rbs_deliver.text

    def select_delivery_pop(self):
        pop_del = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                                  .find_element_by_css_selector("div.b-popup.skin_mini.scheme_null.shadow_on.mod_pickup"))
        WebDriverWait(pop_del, timeout=10).until(lambda dr: dr\
                                      .find_element_by_css_selector("div.b-pickup-points-single-item")).click()
        self_btn = WebDriverWait(pop_del, timeout=10).until(lambda dr: dr\
                                          .find_element_by_css_selector("span.b-sbutton.set_system.scheme_blue"))
        WebDriverWait(self_btn, timeout=10).until(lambda dr: dr.is_enabled() and dr.is_displayed())
        self_btn.click()
    
    def select_delivery_tooltip(self):
        pop_del = ''
        try:
            #If selected without tooltip
            WebDriverWait(self.driver, timeout=2).until(lambda dr: dr\
                        .find_element_by_css_selector("div.b-order-options-list.mod_delivery")\
                        .find_element_by_css_selector("label.b-input-radio.state_checked"))
            return True
        except:
        ##Delivery tooltip
            pop_del = WebDriverWait(self.driver, timeout=7).until(lambda dr: dr\
                                          .find_element_by_css_selector("div.b-tooltip-body"))
        ##Choice random service
        ActionChains(self.driver).move_to_element(pop_del).perform()
        service_lnk = random.choice(WebDriverWait(pop_del, timeout=10).until(lambda dr: \
                                                 [a for a in dr.find_elements_by_name("delivery") if a.is_enabled()]))
        service_lnk.click()
        try:
            ActionChains(self.driver).move_to_element(pop_del).perform()
            random.choice(WebDriverWait(pop_del, timeout=2).until(lambda dr: dr\
                                                      .find_elements_by_name("ot_tod_markup") or \
                                                    dr.find_elements_by_name("ot_insurance"))).click()
        except:
            print "No ot_tod_markupla"

    def fill_basecreds(self, cred_block):
        #Fill base creds
        small_pdata = {'phone':str(random.randrange(9000000000, 9999999999)),\
                       'email':randomword(3, 9)+'@'+randomword(3, 6)+'.'+randomword(2, 3),\
                       'fullname':randomword(3, 9)+' '+randomword(3, 9)+' '+randomword(3, 9)}
        for key in small_pdata.keys():
            inpt = cred_block.find_element_by_name(key)
            if not self.isauth:
                inpt.clear()
                inpt.send_keys(small_pdata[key])
            else:
                self.assertEqual(inpt.get_attribute("value"), saved_small_pdata[key])
        if self.isauth: return saved_small_pdata
        else: return small_pdata
    def fill_shipping_popup(self, newcit_name):
        #Shipping options
        ##Detect button
        #if self.isauth: lnkstyle = "span.g-pseudo.g-link.js-edit"
        #else: lnkstyle = "div.b-order-options-card-body"
        lnkstyle = "span.g-pseudo.g-link.js-edit" if self.isauth \
                    else "div.b-order-options-card-body"
        options_blk = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                            .find_element_by_css_selector("div.b-order-options-list.mod_addresses"))
        self.driver.execute_script("window.scrollBy("+str(options_blk.location["x"])+","\
                                                     +str(options_blk.location["y"]-72)+");")
        ActionChains(self.driver).move_to_element(options_blk\
                                 .find_element_by_css_selector("div.b-order-options-card-h")).perform()
        options_btn = WebDriverWait(options_blk, timeout=4).until(lambda dr: dr\
                                                            .find_element_by_css_selector("div.b-order-options-card-h")\
                                                            .find_element_by_css_selector(lnkstyle))
        WebDriverWait(self.driver, timeout=4).until(lambda dr: options_btn.is_displayed())
        options_btn.click()
        self.catch_bad_popup()
        ##Shipping popup
        addr_pop = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                                          .find_element_by_css_selector("div.b-popup-h"))
        big_pdata = {'fullname':randomword(5, 12),\
                     'postcode':random.randrange(10000, 1000000),\
                     'street':randomword(5, 15),\
                     'house':random.randrange(1, 100),\
                     'block':random.randrange(1, 10),\
                     'flat':random.randrange(1, 10),\
                     'floor':random.randrange(1, 10),\
                     'comment':randomword(6, 59)}
        for key in big_pdata.keys():
            el = addr_pop.find_element_by_name(key)
            if not self.isauth:
                el.clear()
                el.send_keys(big_pdata[key])
            else:
                self.assertEqual(el.get_attribute("value"), saved_big_pdata[key])
        ##New stupid location search
        addr_pop.find_element_by_css_selector("span.g-pseudo.mod_choose-location > span.g-pseudo-h").click()
        ##Location search tooltip
        new_loc_frm = WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                                                .find_element_by_css_selector("form.b-form.mod_location-search"))     
        new_loc_frm.find_element_by_name("location-search").send_keys(newcit_name)
        ##Wait for city suggestion and click.
        try:
            new_loc_frm.find_element_by_name("location-search").click()
            WebDriverWait(self.driver, timeout=10).until(lambda dr: dr\
                                              .find_element_by_css_selector("div.b-suggestion-item")).click()
        except:
            warn("city suggestion wasn't appeared")
            new_loc_frm.find_element_by_name("location-search").send_keys(Keys.ENTER)
        ##If we have an metropolitan
        try:
            metro_cmb = WebDriverWait(addr_pop, timeout=4).until(lambda dr: dr\
                                                    .find_element_by_css_selector("div.b-combobox-field"))
            metro_cmb.click()
            sug_lst = WebDriverWait(self.driver, timeout=6).until(lambda dr: dr\
                            .find_element_by_css_selector("div.b-suggestion-list"))
            metro_cmb.find_element_by_css_selector("input.b-input-field").send_keys([Keys.DOWN]*random.randrange(1,8))
            WebDriverWait(self.driver, timeout=4).until(lambda dr: dr\
                    .find_element_by_css_selector("div.b-suggestion-item.state_active")).click()
            WebDriverWait(driver, timeout=10).until(lambda dr: not self.check_exists(sug_lst))
        except:
            print "Sorry, you haven't an metro. Or anything failed"
        addr_pop.find_element_by_css_selector("input.b-sbutton-input").submit()
        WebDriverWait(self.driver, timeout=3).until(lambda dr: not self.check_exists(new_loc_frm))
        
    def catch_bad_popup(self):
        #Catch bad popup and close
        try:
            self.shot_an_element(\
            WebDriverWait(self.driver, timeout=3).until(lambda dr: dr\
                                                        .find_element_by_css_selector("div.b-popup-h")),\
                                                                        "possible_confirm_reg_change_popup")
            WebDriverWait(self.driver, timeout=3).until(lambda dr: dr\
                                            .find_element_by_css_selector("span.b-sbutton.js-accept")).click()
            WebDriverWait(self.driver, timeout=3).until(lambda dr: dr\
                                            .find_element_by_css_selector("div.b-popup-close")).click()
            return True
        except:
            return False
            print "No bad pop. Ok"
            
    def payment_choose(self):
        #Choose payment type
        pay_blk = self.driver.find_element_by_css_selector("div.b-order-block.mod_payment")
        ##Random choose only active methods
        rbs_pays_all = pay_blk.find_elements_by_css_selector("div.b-order-options-card.toolbar_on")
        rbs_pays_bad = pay_blk.find_elements_by_css_selector("div.b-order-options-card.toolbar_on.state_disabled")
        rbs_pays = [a for a in rbs_pays_all if not a in rbs_pays_bad]
        rbs_pay = random.choice(rbs_pays)
        ActionChains(self.driver).move_to_element(rbs_pay).perform()
        rbs_pay.find_element_by_tag_name("input").click()
        ##Payment topoltip
        try:
            pop_pay = [a for a in WebDriverWait(self.driver, timeout=1).until(lambda dr: dr\
                                              .find_elements_by_css_selector("div.b-tooltip.mod_payments > div.b-tooltip-body"))\
                                              if a.is_displayed()][0]
            ActionChains(self.driver).move_to_element(pop_pay).perform()
        except:
            warn("No payment tooltip found.")
            return
        try:
            WebDriverWait(rbs_pay, timeout=1).until(lambda dr: dr\
                                             .find_elements_by_css_selector("label.b-input-radio.state_checked"))
            return
        except:
            print "Continue choosing payment."
        print "Tooltip opacity is", pop_pay.value_of_css_property('opacity')
        ##Random choice only active option
        rbs_pay_ad_all = [a for a in pop_pay.find_elements_by_css_selector("label.b-input-radio")\
                             if a.is_displayed()]
        #pop_pay.click()
        #if not self.check_exists(pop_pay): return
        rbs_pay_ad_bad = pop_pay.find_elements_by_css_selector("label.b-input-radio.state_disabled")
        rbs_pay_ad = [a for a in rbs_pay_ad_all if not a in rbs_pay_ad_bad]
        input_el = random.choice(rbs_pay_ad)#.find_element_by_tag_name("input")
        try: input_el.click()
        except: input_el.submit()
        self.shot_an_element(input_el, "payment_option", True)
        if self.check_exists(pop_pay):
            self.shot_an_element(pop_pay, "payment_tooltip", True)

    def fill_loyalty(self, default=0):
        #Loyality 
        ln_blk = self.driver.find_element_by_css_selector("div.b-order-block.view_near.mod_bonus")
        ln = ln_blk.find_element_by_name("loyalty_number")
        ln.clear()
        number = str(default or random.randrange(10000000, 19999999))
        #print number, default
        ln.send_keys(number)
        self.shot_an_element(ln_blk, "loyalty_block", True)

    def confirm_order(self, url_before):
        #Confirm order
        self.driver.find_element_by_css_selector("div.b-order-foot-container")\
              .find_element_by_css_selector("input.b-sbutton-input").click()
        #Detect url changed
        WebDriverWait(self.driver, timeout=10).until(lambda dr: not url_before == dr.current_url)

    def fill_promo(self, _word):
        WebDriverWait(self.driver, timeout=10)\
            .until(lambda dr: dr.find_element_by_css_selector("span.g-pseudo.g-link.js-cart-promo-link")).click()
        mag_bd = WebDriverWait(self.driver, timeout=10)\
            .until(lambda dr: dr.find_element_by_css_selector("div.b-tooltip-cart-promocode"))
        WebDriverWait(mag_bd, timeout=10)\
            .until(lambda dr: dr.find_element_by_name("code")).send_keys(_word)
        ActionChains(self.driver).move_to_element(mag_bd).perform()
        mag_bd.find_element_by_css_selector("input.b-sbutton-input").click()
